package org.wlgzs.office_exam_student.servlet.api;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Semaphore;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.wlgzs.office_exam_student.entity.User;
import org.wlgzs.office_exam_student.permission.Authentication;
import org.wlgzs.office_exam_student.service.office.OfficeConfig;
import org.wlgzs.office_exam_student.servlet.BaseServlet;

import com.songminju.jdagger.JDCheck;

/**
 * @author song(mejeesong@qq.com) 2018年1月29日
 *
 */
@WebServlet("/api/receiveOptionQuestion")
public class ReceiveOptionQuestionFile extends BaseServlet {

	private static final long serialVersionUID = 1L;
	
	private final Semaphore semaphore = new Semaphore(300);

	private static final int CACHE_SIZE = 1024 * 8;
	private static final int MAX_SIZE = 1024 * 1024 * 20;
	private static final String TEMP_DIR = OfficeConfig.TEMP_DIR;
	
	private static final String FILETYPE_DOCX = OfficeConfig.FILETYPE_DOCX;
	private static final String FILETYPE_XLSX = OfficeConfig.FILETYPE_XLSX;
	private static final String FILETYPE_PPTX = OfficeConfig.FILETYPE_PPTX;
	
	private static final String RESP_ERR_SIZE = "{\"code\":\"overSize\",\"msg\":\"文件超出规定大小，请重新选择文件\"}";
	private static final String RESP_ERR_500 = "{\"code\":\"500\",\"msg\":\"网络错误，请稍后再试\"}";
	private static final String RESP_ERR_LOGIN = "{\"code\":\"login\",\"msg\":\"请先登录\"}";
	private static final String RESP_ERR_WAIT = "{\"code\":\"login\",\"msg\":\"请先登录\"}";
	private static final String RESP_SUCCESS = "{\"code\":\"success\",\"msg\":\"上传成功。\"}";
	private static final String RESP_ERR_FILE_TYPE = "{\"code\":\"errorFile\",\"msg\":\"失败，请上传docx、pptx、xlsx文件\"}";
	
	private ServletFileUpload upload = null;

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(CACHE_SIZE);
		factory.setRepository(new File(TEMP_DIR));
		upload = new ServletFileUpload(factory);
		upload.setSizeMax(MAX_SIZE);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession ses = req.getSession();
		User user = Authentication.user();
		String indexStr = req.getParameter("index");
		int index = 0;
		try {
			index = Integer.parseInt(indexStr);
		}catch (Exception e) {
			renderString(RESP_ERR_500);
			return;
		}
		if(index < 0) {
			renderString(RESP_ERR_500);
			return;
		}
		if(user == null) {
			renderString(RESP_ERR_LOGIN);
			return;
		}
		Integer examId = (Integer) ses.getAttribute("examId");
		if(examId == null || examId < 0) {
			renderString(RESP_ERR_LOGIN);
			return;
		}
		logger.debug(examId+":"+index);
		//目前存在bug,应限制只能上传一个文件，以后再弄，先测试功能
		try {
			semaphore.acquire();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
			renderString(RESP_ERR_WAIT);
			return;
		}
		List<FileItem> items = null;
		String respStr = null;
		try {
			items = upload.parseRequest(req);
			for (FileItem item : items) {
				String fileName = item.getName();
				logger.debug(fileName);
				int x = fileName.lastIndexOf(".");
				if(x < 1) {
					//由finally块进行返回数据
					respStr = RESP_ERR_FILE_TYPE;
					return;
				}
				String name = fileName.substring(x+1).toLowerCase();
				logger.debug(name);
				if (JDCheck.hasNsNull(name)) {
					respStr = RESP_ERR_FILE_TYPE;
					return;
				}else {
					if(fileName.length() > 50) {
						respStr = RESP_ERR_FILE_TYPE;
					}else {
						if(name.equals(FILETYPE_DOCX) || name.equals(FILETYPE_XLSX) || name.equals(FILETYPE_PPTX)) {
							String dir = OfficeConfig.resolveFileDir(user.getId(),examId, index, name);
							logger.debug(dir);
							File dirFile = new File(dir);
							if(!dirFile.exists()) {
								dirFile.mkdirs();
							}
							File savedFile = new File(dirFile,fileName);
							if(savedFile.exists()) {
								savedFile.delete();
							}
							savedFile.createNewFile();
							item.write(savedFile);
							respStr = RESP_SUCCESS;
						}else {
							respStr = RESP_ERR_FILE_TYPE;
						}
					}
				}
			}
		} catch (SizeLimitExceededException e) {
			respStr = RESP_ERR_SIZE;
		} catch (FileUploadException e) {
			e.printStackTrace();
			respStr = RESP_ERR_500;
		} catch (Exception e) {
			e.printStackTrace();
			respStr = RESP_ERR_500;
		} finally {
			semaphore.release();
			renderString(respStr);
			if(items != null) {
				for(FileItem item:items) {
					item.delete();
				}
			}
		}
	}
}
